package ac.leedsmet.devmanager.cliApp;

import ac.leedsmet.devmanager.core.*;

import java.io.*;
import java.util.LinkedList;
import java.util.Scanner;

/**
 * This class is purely for testing purposes during development
 * @author Samael
 * @version 1.0
 * @see ac.leedsmet.devmanager.core.UserManagerImpl
 * @see ac.leedsmet.devmanager.core.ProjectManagerImpl
 * @see ac.leedsmet.devmanager.core.IssueManagerImpl
 * @see ac.leedsmet.devmanager.core.StoryManagerImpl
*/
public class Application {

    static UserManagerImpl userManager = new UserManagerImpl();
    static ProjectManagerImpl projectManager = new ProjectManagerImpl();
    static IssueManagerImpl issueManager;
    static StoryManagerImpl storyManager;

    private static User CURRENT_USER;
    private static Project CURRENT_PROJECT;

    public static void main(String[] args) {
        displayWelcomeMessage();

        displayMainMenu();

        if (CURRENT_USER != null && CURRENT_PROJECT != null)
            displayProjectMenu(CURRENT_PROJECT, CURRENT_USER);
    }

    private static void displayProjectMenu(Project project, User user) {
        boolean quit = false;
        LinkedList<String> projectMenuOptions = new LinkedList<String>();
        projectMenuOptions.add("Create an Issue");
        projectMenuOptions.add("Create a Story");
        projectMenuOptions.add("View Issues for this project");
        projectMenuOptions.add("View Stories for this project");
        String menuText = createMenu(project.getName() + " Project Menu", projectMenuOptions);

        int selection = 0;
        Scanner scanner = new Scanner(System.in);

        do {
            System.out.print(menuText);
            selection = scanner.nextInt();
            System.out.println();
            switch (selection) {
                case 1:
                    createIssue(project, user);
                    break;
                case 2:
                    createStory(project);
                    break;
                case 3:
                    viewIssues(project);
                    break;
                case 4:
                    viewStories(project);
                    break;
                case 5:
                    quit = true;
                    break;
                default:
                    System.out.println("Invalid Entry!");
            }
        } while (!quit);
    }

    private static Story createStory(Project project) {
        System.out.print("Please enter a name for this story: ");
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        String storyName;
        try {
            storyName = input.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("string error");
            storyName = null;
        }
        storyManager = new StoryManagerImpl(project);
        Story story = storyManager.createStory(storyName);
        System.out.println("\nNew story Created\n  storyId: " + story.getStoryId() + "\n  title: " + story.getTitle() + "\n\n");
        return story;
    }

    private static Issue createIssue(Project project, User user) {
        System.out.print("Please enter a name for this issue: ");
        String issueName;
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        try {
            issueName = input.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            issueName = null;
        }

        issueManager = new IssueManagerImpl(project);

        Issue issue = issueManager.createIssue(issueName, user.getUsername());
        System.out.println(user.getUsername() + " created issue: " + issue.getIssueId() );
        anyKeyToContinue();
        return issue;
    }

    private static void viewUsers() {
        clearScreen();
        if (userManager.getUsers().size() == 0) {
            System.out.println("There are no users available");
            return;
        }
        System.out.println("\nUsers");
        for (User user : userManager.getUsers()) {
            System.out.println("  id: " + user.getUserId() + "  \tusername: " + user.getUsername());
        }
        anyKeyToContinue();
    }

    private static void viewProjects() {
        clearScreen();
        if (projectManager.getProjects().size() == 0) {
            System.out.println("There are no projects available");
            return;
        }
        System.out.println("\nProjects");
        for (Project project : projectManager.getProjects()) {
            System.out.println("  id: " + project.getProjectId() + "  \tname: " + project.getName());
        }
        anyKeyToContinue();
    }

    private static void viewIssues(Project project) {
        clearScreen();
        if (project.getIssues().size() == 0) {
            System.out.println("There are no issues related to this project");
            return;
        }
        System.out.println("\nIssues");
        for (Issue issue : project.getIssues()) {
            System.out.println("  id: " + issue.getIssueId() + "  \tname: " + issue.getTitle());
        }
        anyKeyToContinue();
    }

    private static void viewStories(Project project) {
        clearScreen();
        if (project.getStories().size() == 0) {
            System.out.println("There are no Stories related to this project");
            return;
        }
        System.out.println("\nStories");
        for (Story story : project.getStories()) {
            System.out.println("  id: " + story.getStoryId() + "  \tname: " + story.getTitle());
        }
        anyKeyToContinue();
    }

    private static User createUser() {
        System.out.print("Please provide a username: ");
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        String username;
        try {
            username = input.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            username = null;
        }
        User user = userManager.createUser(username, "password");
        System.out.println("\nNew User Created\n  userId: "+ user.getUserId() + "\n  username: " + username + "\n  password: password\n");
        CURRENT_USER = user;
        System.out.println("This user is now the active user");
        anyKeyToContinue();
        return user;
    }

    private static Project createProject() {
        System.out.println("Please enter a name for your project");
        String projectName;
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        try {
            projectName = input.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            projectName = null;
        }
        Project project = projectManager.createProject(projectName);
        long projectId = project.getProjectId();
        System.out.println("  Created project id: " + projectId);
        CURRENT_PROJECT = project;
        System.out.println("This is now the active project");
        anyKeyToContinue();
        return project;
    }

    private static void displayMainMenu() {
        boolean quit = false;

        LinkedList<String> mainMenuOptions = new LinkedList<String>();
        mainMenuOptions.add("Create a new project");
        mainMenuOptions.add("Create a new user");
        mainMenuOptions.add("View current projects");
        mainMenuOptions.add("View current users");
        String menuText = createMenu("Main Menu", mainMenuOptions);

        int selection = 0;
        Scanner scanner = new Scanner(System.in);

        do {
            System.out.print(menuText);
            selection = scanner.nextInt();
            System.out.println();
            switch (selection) {
                case 1:
                    createProject();
                    break;
                case 2:
                    createUser();
                    break;
                case 3:
                    viewProjects();
                    break;
                case 4:
                    viewUsers();
                    break;
                case 5:
                    quit = true;
                    break;
                default:
                    System.out.println("Invalid Entry!");
            }
        } while (!quit);
    }

    /**
     * This method will generate the text required to display a menu INPUT the console (44 characters wide).
     * The title and options will be truncated if over 30 characters long.
     */
    private static String createMenu(String title, LinkedList<String> options) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("\n\n============================================\n|   ");
        if (title.trim().length() > 30) {
            title = title.substring(1, 27)+ "...";
        } else {
            title = title.trim();
        }
        stringBuilder.append(title);
        for (int counter = 0; counter < 30 - title.length(); counter++)
            stringBuilder.append(" ");

        stringBuilder.append("         |\n============================================\n");
        stringBuilder.append("| Options:                                 |\n");

        for (String option : options) {
            stringBuilder.append("|    ").append(options.indexOf(option) +1).append(". ");
            if(option.trim().length() > 30)
                option = option.substring(1, 27) + "...";
            else option = option.trim();
            stringBuilder.append(option);
            for (int counter = 0; counter < 30 - option.length(); counter++)
                stringBuilder.append(" ");
            stringBuilder.append("     |\n");
        }
        // There should always be an exit option
        stringBuilder.append("|    ").append(options.size() +1).append(". Exit                               |\n");
        stringBuilder.append("============================================\n\n Select option: ");

        return stringBuilder.toString();
    }

    private static void displayWelcomeMessage() {
        System.out.print("\nWelcome to the Dev Manager Console Application!\n");
        anyKeyToContinue();
    }

    private static void clearScreen() {
        System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
    }

    private static void anyKeyToContinue() {
        System.out.print("\nPress any key to continue");
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        try {
            input.read();
        } catch (IOException e) {
        }
        clearScreen();
    }
}
